package futbol.tacticas.concursantes.TacticaCopiaPatetics;

import futbol.tacticas.*;
import futbol.tacticas.concursantes.Tactica;
import java.awt.*;
import java.util.*;

public class TacticaCopiaPatetics implements Tactica {
    
    Random rand=new Random();
    
    /**Nombre del Equipo*/
    public String getNombre() {
        return "kingkong";
    }
    
    private int c0;
    private int c1;
    private int c2;
    /**Color de la camiseta*/
    public Color getColor1() {
        c0=(c0+10)%512;
        c1=Math.abs(c0-255);
        c2=Math.abs(c1-255);
        return new Color(c2,0,c1);
    }
    /**Color del pantalon*/
    public Color getColor2() {
        return new Color(c1,0,c2);
    }
    /**Color del numero*/
    public Color getColorNumero() {
        return Color.WHITE;
    }
    
    public final int fuerza[]=sfuerza;
    public static int sfuerza[]=new int[]
    {7,7, 6,6, 5,5, 7,7 ,7,7,7};
    
    private int posiciones[][]=sposiciones;
    public static int sposiciones[][]=new int[][]
    {{-140,15},{-140,-15}, {-60,60},{-80,-60}, {0,20},{0,-20}, {50,50},{50,-50}, {100,80},{120,0},{100,-80}};
    
    private int[][] velocidad=new int[11][2];
    /**Retorna la fuerza de un jugador*/
    public int getFuerza(int n) {
        velocidad[n][0]=10-fuerza[n];
        return fuerza[n];
    }
    
    /**Retorna la velocidad de un jugador, en un equipo*/
    public int getVelocidad(int n,int e){
        return velocidad[n][e];
    }
    
    /**Retorna la coordenada x inicial del un jugador*/
    public int getXInicial(int n) {
        return posiciones[n][0];
    }
    
    /**Retorna la coordenada y inicial del un jugador*/
    public int getYInicial(int n) {
        return posiciones[n][1];
    }
    
    /**Retorna el angulo entre dos coordenadas*/
    private double angulo(double x1, double y1, double x0, double y0){
        return angulo(x1-x0,y1-x0);
    }
    
    /**Retorna el angulo de una cordenada*/
    private double angulo(double dx,double dy){
        double ang=0;
        if (dx>0) ang=Math.atan(dy/dx);
        else if (dx<0) ang=Math.atan(dy/dx)+Math.PI;
        else if (dx<0) ang=Math.PI/2;
        else ang=-Math.PI/2;
        ang=corregirAngulo(ang);
        return ang;
    }
    
    /**Uso interno*/
    private double corregirAngulo(double ang){
        while (ang<0)
            ang+=Math.PI*2;
        while (ang>=Math.PI*2)
            ang-=Math.PI*2;
        return ang;
    }
    
    /**Retorna la distancia entre dos coodenadas*/
    private double distancia(double x1,double y1,double x0,double y0){
        double dx=(x1-x0);
        double dy=(y1-y0);
        return distancia(dx,dy);
    }
    
    /**Retorna la distancia de una coordenada*/
    private double distancia(double dx,double dy){
        return Math.sqrt(dx*dx+dy*dy);
    }
    
    private boolean log=true;
    private void log(String msg){
        //if (log)
        //    System.out.print(msg);
    }
    
    double d1,d0,a1,a0;
    int bx0=0,bx1=0,bx2=0,by0=0,by1=0,by2=0,_bx1,_by1,_bx0,_by0,v;
    int _bx,_by,c,_c0=0;
    int bx[],by[];
    int x[][]=new int[11][2];
    int y[][]=new int[11][2];
    int p[][]=new int[11][2];
    Point ca[]=new Point[11];
    Vector vector=new Vector();
    Point[][] jug=new Point[11][2];
    boolean nn=true,nnn=false;
    boolean b0;
    /**Retorna las acciones a ejecutar*/
    public Vector<Comando> getComandos(SituacionJugadores sj) {
        vector.clear();
        nnn=false;
        for(int i=0;i<11;i++){
            ca[i]=jug[i][1];
            jug[i][0]=sj.getMisJugadores()[i];
            jug[i][1]=sj.getContrario()[i];
        }
        bx2=bx1;by2=by1;
        b0=false;
        
        if (b0){
            bx0=_bx0;
            by0=_by0;
        }
        
        bx1=bx0;by1=by0;
        _bx1=bx0;_by1=by0;
        Point b=sj.getBola();
        bx0=b.x;by0=b.y;
        if (Math.abs(bx0)>=160 && Math.abs(by0)<=30){
            for(int i=0;i<100;i++){
                int i1=rand.nextInt(11);
                int i2=rand.nextInt(11);
                if (i1!=i2 && getFuerza(i1)==getFuerza(i2)){
                    int x=posiciones[i1][0];
                    int y=posiciones[i1][1];
                    posiciones[i1][0]=posiciones[i2][0];
                    posiciones[i1][1]=posiciones[i2][1];
                    posiciones[i2][0]=x;
                    posiciones[i2][1]=y;
                }
            }
        }
        
        a0=angulo(bx2-bx1,by2-by1);
        a1=angulo(bx1-bx0,by1-by0);
        d0=distancia(bx1,by1,bx0,by0);
        d1=distancia(bx2,by2,bx1,by1);
        if (d0>100){
            d0=0;
            d1=0;
            bx1=0;by1=0;
            bx2=0;by2=0;
            _c0=c-1;
            _bx=0;_by=0;
            
        } else {
            if (!nn){
                int di;
                for(int i=0;i<11;i++){
                    di=(int)Math.floor(distancia(jug[i][1].x,jug[i][1].y,ca[i].x,ca[i].y));
                    if (velocidad[i][1]<di)
                        velocidad[i][1]=di;
                }
            }
        }
        nn=false;
        if (d0>3 && (Math.abs(a0-a1)>.20 || Math.abs(d1-d0)>5)){
            _bx=bx1;
            _by=by1;
            _c0=c-1;
        }
        double n=(double)(c-_c0);
        double d=distancia(bx0,by0,_bx,_by);
        v=Math.max((int)Math.round(d/n-(n+1d)/2d),0);
        _bx0=_bx1;_by0=_by1;
        if (v>21){
            if (_by0<-120){
                _by0=-240-_by0;
            }
            
            if (_by0>120){
                _by0=240-_by0;
            }
            
            if (_bx0<-160){
                _bx0=-320-_bx0;
            }
            if (_bx0>160){
                _bx0=320-_bx0;
            }
            b0=true;
        }
        
        
        bx=new int[v+1];
        by=new int[v+1];
        bx[v]=bx0;
        by[v]=by0;
        if (v>0){
            double dist=distancia(_bx,_by,bx0,by0);
            double dx=(double)(bx0-_bx)/dist;
            double dy=(double)(by0-_by)/dist;
            for(int i=v;i>0;i--){
                bx[i-1]=bx[i]+(int)Math.round(dx*(double)i);
                by[i-1]=by[i]+(int)Math.round(dy*(double)i);
                if (by[i-1]<-120){
                    by[i-1]=-240-by[i-1];dy=-dy;
                    if (i==v){
                        _by=-240-_by;
                        by0=-240-by0;
                        by1=-240-by1;
                        by2=-240-by2;
                    }
                }
                if (by[i-1]>120){
                    by[i-1]=240-by[i-1];dy=-dy;
                    if (i==v){
                        _by=240-_by;
                        by0=240-by0;
                        by1=240-by1;
                        by2=240-by2;
                    }
                }
                if (bx[i-1]<-160){
                    bx[i-1]=-320-bx[i-1];dx=-dx;
                    if (i==v){
                        _bx=-320-_bx;
                        bx0=-320-bx0;
                        bx1=-320-bx1;
                        bx2=-320-bx2;
                    }
                }
                if (bx[i-1]>160){
                    bx[i-1]=320-bx[i-1];dx=-dx;
                    if (i==v){
                        _bx=320-_bx;
                        bx0=320-bx0;
                        bx1=320-bx1;
                        bx2=320-bx2;
                    }
                }
            }
        }
        
        
        for(int i=0;i<11;i++){
            int jm=Math.max(Math.min(14,v-1),0);
            int bx_=sj.getMisJugadores()[i].x;
            int by_=sj.getMisJugadores()[i].y;
            d1=getVelocidad(i,0);
            p[i][0]=-1;
            for(int j=jm;j>0;j--){
                d0=Math.max(0,distancia(bx_,by_,bx[j],by[j])-10d)/d1;
                if (d0<(v-j)){
                    p[i][0]=v-j;
                    x[i][0]=bx[j];
                    y[i][0]=by[j];
                    break;
                }
            }
            if (p[i][0]==-1){
                d0=Math.max(0,distancia(bx_,by_,bx[0],by[0])-10d)/d1;
                if ((d0-Math.floor(d0))>0)
                    d0=Math.floor(d0)+1;
                else
                    d0=Math.floor(d0);
                p[i][0]=(int)d0;
                x[i][0]=bx[0];
                y[i][0]=by[0];
            }
        }
        ganarPosicion();
        paseInteligente();
        c++;
        return vector;
    }
    
    private void ganarPosicion(){
        int min=Integer.MAX_VALUE;
        for(int i=0;i<11;i++)
            if (p[i][0]<min)
                min=p[i][0];
        for(int i=0;i<11;i++)
            if (min==p[i][0])
                vector.add(new ComandoIrA(i,x[i][0],y[i][0]));
            else
                vector.add(new ComandoIrA(i,getXInicial(i),getYInicial(i)));
    }
    
    
    private int zonaMuerta[]={0,0,0,0,0,15,55,107};
    private void paseInteligente(){
        int mejor=0;
        int px=-1000;
        if (bx.length<=15){
            for(int i=0;i<11;i++){
                if (distancia(jug[i][0].x,jug[i][0].y,bx0,by0)<=10){
                    if (jug[i][0].x<-120){
                        int[] puntaje=new int[36];
                        
                        //for(int i=0;i<360;i=i+10){
                            
                        //}
                    }
                    if (distancia(bx0,by0,160,0)<=(zonaMuerta[getFuerza(i)]+20)){
                        vector.add(new ComandoTiroAPuerta(i,0));//tiro al arco
                    } else {
                        int next;
                        int it=0;
                        do{
                            while((next=rand.nextInt(11))==i);
                            it++;
                            if (jug[next][0].x>px){
                                px=jug[next][0].x;
                                mejor=next;
                            }
                        } while(jug[mejor][0].x<jug[i][0].x && it<100);
                        int dx=jug[mejor][0].x;
                        int dy=jug[mejor][0].y;
                        double dist=distancia(dx,dy,bx0,by0);
                        int fuerza;
                        if (dist>90)
                            fuerza=7;
                        else if (dist>40)
                            fuerza=6;
                        else fuerza=4;
                        vector.add(chutear(i,jug[mejor][0].x,jug[mejor][0].y,fuerza));
                    }
                }
            }
        }
    }
    
    private ComandoGolpearBola chutear(int nJug,int x,int y,int fuerza){
        double dx=x-jug[nJug][0].x;
        double dy=y-jug[nJug][0].y;
        if (dx!=0 && dy!=0){
            double dist=distancia(dx,dy);
            dx=dx/dist;dy=dy/dist;
            int f=Math.min(getFuerza(nJug),fuerza);
            double d=50d*(double)f/(double)getFuerza(nJug);
            double dd=d,ddx=dx,ddy=dy;
            int ff;
            do{
                dx=(int)((double)ddx*dd);
                dy=(int)((double)ddy*dd);
                dist=distancia(dx,dy);
                ff=getFuerza(nJug)*(int)dist/52;
                dd++;
            } while (ff<f);
            return new ComandoGolpearBola(nJug,jug[nJug][0].x+dx,jug[nJug][0].y+dy);
        } else
            return new ComandoGolpearBola(nJug,jug[nJug][0].x,jug[nJug][0].y);
    }
    
    private void beep(){
        //java.awt.Toolkit.getDefaultToolkit().beep();
    }
    
}

